home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Trading on the Edge
/
Trading On The Edge - CD-ROM Toolkit (Wayzata Technology)(2031)(1994).bin
/
mac
/
Mac_Files
/
Software Utilities
/
NN PreProcessing
/
FINNLDS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-30
|
27KB
|
749 lines
/* 15:14 09-20-92 (finnlds.c) Non-linear Dynamical System Analysis */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/************************************************************************
* Copyright(C) 1992 High-Tech Communications. *
* 103 Buckskin Court, Sewickley, PA 15143 *
* *
* Written by Casimir C. Klimasauskas *
* *
* All rights reserved. No part of this program may be reproduced, *
* stored in a retrieval system, or tramsmitted, in any form or by any *
* means, electronic, mechanical, photocopying, recording or otherwise *
* without the prior written permission of the copyright owner, *
* High-Tech Communications. *
* *
* These programs are supplied on an "as-is" basis with no warranties *
* of fitness or operability, either express or implied. *
* *
************************************************************************
*/
#define ASof(x) (sizeof(x)/sizeof(x[0]))
#define EMIN (1.e-15)
/* The routines in this module were translated by or created by
* Casimir C. Klimasauskas. Due to a lack of reference data and
* the numerical intensity of the computations, no guarantee can
* be made that the procedures are correct.
*/
/************************************************************************
* *
* Interface Definintion *
* *
************************************************************************
These routines have been interfaced to the utilities developed and
described in the previous issue of Advanced Technology for Developers.
From the main menu:
hurst - enter the "hurst" analysis section
series = series.label,start,end - enter a new series
startwindowsize = 2 - initial window size
deltawindowsize = 2 - amount to increment window size
iterations = 20 - number of iterations (max 100)
derivative = no - use derivative of series
printfile = untitled.prn,type - print output file name
type: tab, comma, text
type [file] - type a file to the screen
go - execute the command
quit - return to main menu system
correlationdim - enter correlation dim
series = series.label,start,end - enter a new series
embedding = 5 - embedding dimension
tau = 2 - lag for phase space
{ radius = 0.1 - initial radius }
{ delta = 0.1 - increment for radius }
iterations = 20 - number of iteraitons (max 100)
printfile = untitled.prn,type - print output file
type: tab, comma, text
type [file] - type a file to the screen
go [startdim,enddim] - run with embedding =start..end
quit
lyapunov - enter lyapunov section
series = series.label,start,end - enter a new series
embedding = 5 - embedding dimension
tau = 2 - lag for phase space
minscale = 0.1 - minimum radius
maxscale = 1.5 - maximum radius
evolve = 3 - number of time steps per evolution
lagminimum = 2 - minimum lag between points
printfile = untitled.prn,type - print output file
type: tab, comma, text
type [file] - type a file to the screen
go [startdim,enddim] - run with embedding =start..end
quit
*/
/************************************************************************
* *
* Utilities Requried in Computation of Various Parameters *
* *
************************************************************************
*/
/* --- AverageD() --- Compute the average of a series of data points */
static double AverageD( vFP, n ) /* compute the average of a series */
float *vFP; /* pointer to floating vector */
int n; /* number of items in list */
{ double v=0.; /* work accumulator */
int i=n; /* work index */
while( --i >= 0 ) v += *vFP++;
return( n>0? (v/((double)n)):0. );
}
/* --- StdDevD() --- Compute the standard deviation of data points */
static double StdDevD( vFP, n ) /* compute the standard deviation */
float *vFP; /* pointer to vector */
int n; /* # of items in series */
{ double XBarD=0.; /* average */
double DevD=0.; /* standard deviation */
double vD; /* work value */
int i; /* work counter */
float *FP; /* work float pointer */
if ( n > 1 ) {
/* NOTE: use this method to compute standard deviation to
* reduce problems with round-off errors when the average is
* very different from zero.
*/
for( FP=vFP, i=n; --i >= 0; ) XBarD += *FP++;
XBarD /= (double)n;
for( FP=vFP, i=n; --i >= 0; ) {
vD = (XBarD - *FP++);
DevD += vD * vD;
}
DevD = sqrt( DevD / n );
return( DevD );
}
return( 0. );
}
/* --- RegressI() --- Perform linear regression on two series --- */
static int RegressI( mDP, bDP, xFP, yFP, n ) /* compute regression line */
double *mDP; /* slope */
double *bDP; /* intercept: y = mx + b */
float *xFP; /* x-vector */
float *yFP; /* y-vector */
int n; /* length of vector */
{ double XBarD=0.; /* x-average */
double YBarD=0.; /* y-average */
double NumD=0.; /* numerator */
double DenD=0.; /* denominator */
double v; /* work value */
double m, b; /* slope, intercept */
register float *aFP, *bFP; /* work pointers */
register int i; /* work counter */
/* NOTE: this method is used to compute the regression equations,
* because it is much more stable than the numerically "quicker"
* methods if the mean for X & Y differ significantly from zero.
*/
for( aFP=xFP,bFP=yFP,i=n; --i >= 0; ) {
XBarD += *aFP++; YBarD += *bFP++;
}
/* --- handle too few points for valid regression --- */
if ( n < 2 ) { m = 0.0; b = YBarD; goto Done; }
XBarD /= (double)n;
YBarD /= (double)n;
for( aFP=xFP,bFP=yFP,i=n; --i >= 0; ) {
v = *aFP++ - XBarD;
NumD += v * (*bFP++ - YBarD);
DenD += v * v;
}
m = NumD / (DenD > EMIN? DenD:EMIN );
b = YBarD - m * XBarD;
Done:
if ( mDP ) *mDP = m;
if ( bDP ) *bDP = b;
return( 0 );
}
/************************************************************************
* *
* HurstI() - Hurst Coefficient Computations *
* *
************************************************************************
NOTE: the return vectors are always of length "IterN" long. They
must be allocated at least this length.
hurstFP[0] = Hurst coefficient over all windows
hurstFP[1] = Hurst coefficient over windows 0,1,2
hurstFP[2] = Hurst coefficient over windows 1,2,3
...
*/
#define HREG 5 /* number of items for regression line */
int HurstI( hurstFP, nFP, rsFP, lognFP, logrsFP,
xFP, nxI, StartN, DeltaN, IterN, DiffFI )
float *hurstFP; /* (r) hurst coefficients */
float *nFP; /* (r) number of windows */
float *rsFP; /* (r) R/S raw */
float *lognFP; /* (r) log (number of windows) (x) */
float *logrsFP; /* (r) log (R/S) (y) */
float *xFP; /* (i) time-series as a vector */
int nxI; /* (i) # of items in time series */
int StartN; /* (i) starting window size */
int DeltaN; /* (i) amount to increase window size */
int IterN; /* (i) # of iterations */
int DiffFI; /* (i) =0, use raw data; =1, use diffs */
{
float *wxFP=0; /* work vector */
float *rswFP=0; /* work RS vector (rscolumn+6) */
double MD, SD, RSD; /* M=Average; S=Std Dev; RSD=R/S */
double MnD, MxD; /* min & max */
double SumXtD; /* total Xt (running) */
double SlopeD; /* slope of the regression line */
double InterceptD; /* intercept of the regression line */
float vF; /* floating work value */
int CounterI; /* current iteration */
int WindowSizeI; /* current window size */
int NoOfWindowsI; /* number of windows */
int WindI; /* window number */
float *FP; /* work float pointer */
int wxI; /* work index */
int rcI=0; /* return code */
/* --- clear out results area --- */
for( wxI = 0; wxI < IterN; wxI++ ) {
nFP[wxI] = 0.;
rsFP[wxI] = 0.;
lognFP[wxI] = 0.;
logrsFP[wxI] = 0.;
hurstFP[wxI] = 0.;
}
/* --- allocate dynamic memory --- */
wxFP = (float *)malloc( ((unsigned)nxI+2) * sizeof(float) );
rswFP = (float *)malloc( ((unsigned)nxI+2) * sizeof(float) );
if ( wxFP == (float *)0 || rswFP == (float *)0 ) {
rcI = -1;
goto Done;
}
/* --- copy over the series or the difference --- */
if ( DiffFI ) nxI--; /* one less item if diffs */
for( wxI = 0; wxI < nxI; wxI++ ) {
if ( DiffFI ) {
if ( xFP[wxI] < EMIN || xFP[wxI+1] < EMIN ) vF = 1.;
else vF = log(xFP[wxI+1]) / log(xFP[wxI]);
} else vF = xFP[wxI];
wxFP[wxI] = vF;
}
/* --- go through each iteration --- */
WindowSizeI = StartN; /* starting window size */
for( CounterI = 0; CounterI < IterN; CounterI++ ) {
/* --- Compute the number of windows --- */
NoOfWindowsI = nxI / WindowSizeI; /* # of windows */
if ( NoOfWindowsI < 1 ) break; /* nothing more to do */
/* --- process each window --- */
for( WindI = 0; WindI < NoOfWindowsI; WindI++ ) {
FP = &wxFP[ WindI * WindowSizeI ]; /* start of this window */
MD = AverageD( FP, WindowSizeI ); /* Average */
SD = StdDevD( FP, WindowSizeI ); /* Standard Deviation */
SumXtD = 0.;
for( wxI = 0; wxI < WindowSizeI; wxI++ ) {
SumXtD += (FP[wxI] - MD);
if ( wxI == 0 || SumXtD < MnD ) MnD = SumXtD;
if ( wxI == 0 || SumXtD > MxD ) MxD = SumXtD;
}
RSD = (MxD - MnD) / (SD < EMIN? EMIN:SD);
rswFP[WindI] = RSD; /* R/S for this window */
}
/* --- Compute RS --- */
RSD = AverageD( rswFP, NoOfWindowsI );
rsFP[ CounterI] = RSD;
nFP[ CounterI] = WindowSizeI;
logrsFP[CounterI] = log( RSD );
lognFP[ CounterI] = log( (double)WindowSizeI );
/* --- Compute the next window size --- */
if ( DeltaN == 0 ) WindowSizeI *= StartN; /* geometric */
else WindowSizeI += DeltaN; /* linear */
}
/* --- compute regression line --- */
RegressI( &SlopeD, &InterceptD, lognFP, logrsFP, CounterI );
hurstFP[0] = pow( 2., (2.*SlopeD-1.) ) - 1.; /* full regression */
for( wxI = 1; wxI < CounterI-(HREG-2); wxI++ ) {
RegressI( &SlopeD, &InterceptD, &lognFP[wxI-1], &logrsFP[wxI-1], HREG );
hurstFP[wxI] = pow( 2., (2.*SlopeD-1.) ) - 1.; /* 3-point regression */
}
Done:
if ( wxFP != (float *)0 ) free( (void *)wxFP );
if ( rswFP != (float *)0 ) free( (void *)rswFP );
return( rcI );
}
/************************************************************************
* *
* CorrDimI() - Correlation Dimension *
* *
************************************************************************
NOTE: Each of the return vectors MUST be of length NIterI or greater.
For each iteration, using the embedding dimension DimI, and
re-constructing the phase space with a lag of tauI, the
distance, correlation dimension, log(distance) and log(cd) are
computed and stored.
The regression coefficients for log(distance)[x] & log(cd)[y] is
computed for all of the points in the iteration as well as
groups of 3 points at a time.
NOTE: the accompanying wingz scripts comptue the correlation
dimension for a range of embedding dimensions. This routine
computes it for only a single embedding dimension.
*/
int CorrDimI( rFP, crFP, logrFP, logcrFP, regFP,
xFP, nI, DimI, tauI, dtD, RD, NIterI )
float *rFP; /* (r) distance */
float *crFP; /* (r) correlation dimension */
float *logrFP; /* (r) log (distance) */
float *logcrFP; /* (r) log (correlation dimension) */
float *regFP; /* (r) regression of x=log(dist) vs y=log(cd) */
register float *xFP; /* (i) input vector */
int nI; /* (i) length of input vector */
int DimI; /* (i) embedding dimension */
int tauI; /* (i) time lag for re-constructing phase space */
double dtD; /* (i) change in distance each iteration */
double RD; /* (i) initial distance */
int NIterI; /* (i) number of iterations to make */
{
int i,j,k; /* work indicies */
int itI, ktI; /* derived work indicies */
int nptI; /* # of points */
int StopI; /* flag to stop iterating */
double D; /* distance */
double RRD; /* current distance squared */
double CRD; /* correlation dimension */
long ThetaL; /* count of "hits" */
int rcI=0; /* return code */
int wxI; /* work index */
double vD; /* work value */
/* NOTE: the following computations are based on Equation (12.2)
* in "Chos & Order in the Capital Markets"..
*/
nptI = nI - DimI * tauI; /* max points in embedding dimension */
for( StopI = 0; StopI < NIterI; StopI++ ) {
ThetaL = 0; /* # of phase-space points in radius RD */
RRD = RD * RD; /* square of current distance */
/* NOTE: use this rather than computing the square-root:
* if a > b -> a*a > b*b where a>0 && b>0.
*/
for( k = 0; k < nptI; k++ ) {
/* NOTE: take advantage of the fact that we are computing
* the square of the difference between ZFP[j,k] & ZFP[j,i].
* We need only compute the upper part of a triangular matrix
* and multiply ThetaL by 2 at the end.
*/
for( i = k+1; i < nptI; i++ ) {
D = 0.; /* distance */
itI = i; /* work surrogate for i */
ktI = k; /* work surrogate for k */
for( j = 0; j < DimI; j++ ) {
/* ZFP[j,i] = xFP[j*tauI + i] */
/* ZFP[j,k] = xFP[j*tauI + k] */
/* vD = ZFP[j,k] - ZFP[j,i]; */
vD = xFP[ktI] - xFP[itI]; /* distance */
D += vD * vD; /* squared distance */
itI += tauI; /* update phase dimension */
ktI += tauI;
}
if ( D < RRD ) ThetaL++; /* within the radius */
}
}
vD = ((double)nptI-1.) * ((double)nptI); /* adjust for i <> k */
CRD = 2.*((double)ThetaL) / vD; /* correlation dimension */
/* NOTE: factor of 2 to compensate for only computing upper
* triangular part of the matrix
*/
rFP[StopI] = RD; /* current distance */
crFP[StopI] = CRD; /* current correlation dimension */
logrFP[StopI] = RD>EMIN? log(RD):0.; /* log(distance) */
logcrFP[StopI] = CRD>EMIN? log(CRD):0.; /* log(cd) */
RD += dtD; /* increment the distance */
}
/* --- Compute the slope --- */
RegressI( &D, &vD, &logrFP[0], &logcrFP[0], StopI );
regFP[0] = D;
for( StopI = 1; StopI < NIterI-1; StopI++ ) {
RegressI( &D, &vD, &logrFP[StopI-1], &logcrFP[StopI-1], 3 );
regFP[StopI] = D;
}
regFP[StopI] = 0.; /* make things clean */
Done:
return( rcI );
}
/************************************************************************
* *
* CorrDim2I() - Alternate Computation of Correlation Dimension *
* *
************************************************************************
NOTE: Each of the return vectors MUST be of length NIterI or greater.
For each iteration, using the embedding dimension DimI, and
re-constructing the phase space with a lag of tauI, the
distance, correlation dimension, log(distance) and log(cd) are
computed and stored.
The regression coefficients for log(distance)[x] & log(cd)[y] is
computed for all of the points in the iteration as well as
groups of 3 points at a time.
This program automatically computes the minimum radius (RD) and
the delta radius (dtD) based on the minimum radius, maximum radius,
and the number of iterations.
*/
#define RCORR 5 /* regression correlation */
int CorrDim2I( rFP, crFP, logrFP, logcrFP, regFP,
xFP, nI,
DimI, tauI, NIterI )
float *rFP; /* (r) distance */
float *crFP; /* (r) correlation dimension */
float *logrFP; /* (r) log (distance) */
float *logcrFP; /* (r) log (correlation dimension) */
float *regFP; /* (r) regression of x=log(dist) vs y=log(cd) */
register float *xFP; /* (i) input vector */
int nI; /* (i) length of input vector */
int DimI; /* (i) embedding dimension */
int tauI; /* (i) time lag for re-constructing phase space */
int NIterI; /* (i) number of iterations to make */
{
int i,j,k; /* work indicies */
int itI, ktI; /* derived work indicies */
int nptI; /* # of points */
double D; /* distance */
double RD; /* current raidus */
double dtD; /* increment in radius */
double CRD; /* correlation dimension */
long ThetaL, wL; /* count of "hits" */
int rcI=0; /* return code */
int wxI; /* work index */
double vD; /* work value */
int FirstFlagI; /* first time through flag */
double RMinD; /* minimum distance */
double RMaxD; /* maximum distance */
double RSclD, ROffD; /* scale & offset for sorting */
long *ThetaLP=0; /* work array */
int WIterI; /* work iterations */
int WMinXI; /* minimum index */
if ( NIterI < 10 ) { return( -1 ); }
nptI = nI - DimI * tauI; /* max points in embedding dimension */
ThetaLP = (long *)malloc( NIterI*sizeof(long) );
if ( ThetaLP == (long *)0 ) {
rcI = -1;
goto Done;
}
memset( (void *)ThetaLP, 0, NIterI*sizeof(long) );
for( wxI = 0; wxI < NIterI; wxI++ ) {
rFP[wxI] = 0.0;
crFP[wxI] = 0.0;
logrFP[wxI] = 0.0;
logcrFP[wxI] = 0.0;
regFP[wxI] = 0.0;
}
/* --- Compute the Min/Max Distance between points --- */
RMinD = RMaxD = 0;
FirstFlagI = 1;
for( k = 0; k < nptI; k++ ) {
for( i = k+1; i < nptI; i++ ) {
D = 0.; /* distance to point in phase space */
itI = i; /* work surrogate for i */
ktI = k; /* work surrogate for k */
for( j = 0; j < DimI; j++ ) { /* phase space on the fly */
vD = xFP[ktI] - xFP[itI]; /* distance */
D += vD * vD; /* squared distance */
itI += tauI; /* update phase dimension */
ktI += tauI;
}
D = sqrt( D ); /* euclidean distance */
if ( FirstFlagI ) { RMinD = RMaxD = D; FirstFlagI = 0; }
else if ( D < RMinD ) RMinD = D;
else if ( D > RMaxD ) RMaxD = D;
}
}
/* --- Compute the Scale / Offset to sort into bins --- */
if ( (RMaxD - RMinD) < EMIN ) {
rcI = -2;
goto Done;
}
WIterI = 3 * NIterI; /* part of space to explore */
WMinXI = NIterI; /* first part to ignore */
RSclD = ((double)WIterI) / (RMaxD - RMinD);
ROffD = -RSclD * RMinD - WMinXI;
/* --- Sort everything into bins --- */
for( k = 0; k < nptI; k++ ) {
for( i = k+1; i < nptI; i++ ) {
D = 0.; /* distance to point in phase space */
itI = i; /* work surrogate for i */
ktI = k; /* work surrogate for k */
for( j = 0; j < DimI; j++ ) { /* phase space on the fly */
vD = xFP[ktI] - xFP[itI]; /* distance */
D += vD * vD; /* squared distance */
itI += tauI; /* update phase dimension */
ktI += tauI;
}
D = sqrt( D ); /* euclidean distance */
wxI = RSclD * D + ROffD; /* index into table */
if ( wxI < 0 ) wxI = 0;
if ( wxI < NIterI ) ThetaLP[wxI] += 2; /* acct for full mtx */
}
}
/* --- Compute the Correlation Dimension --- */
vD = ((double)nptI - 1.) * ((double)nptI); /* adjust for i <> k */
ThetaL = 0;
dtD = (RMaxD - RMinD) / ((double)WIterI); /* space between bins */
RD = RMinD + (WMinXI+1) * dtD; /* first radius */
for( wxI = 0; wxI < NIterI; wxI++ ) {
ThetaL += ThetaLP[wxI]; /* cumulative count */
CRD = ((double)ThetaL) / vD; /* correlation dimension */
rFP[wxI] = RD; /* current distance */
crFP[wxI] = CRD; /* current correlation dimension */
logrFP[wxI] = RD>EMIN? log(RD):0.; /* log(distance) */
logcrFP[wxI] = CRD>EMIN? log(CRD):0.; /* log(cd) */
RD += dtD; /* increment the distance */
}
/* --- Compute the slope --- */
RegressI( &D, &vD, &logrFP[0], &logcrFP[0], NIterI );
regFP[0] = D;
for( wxI = 1; wxI < NIterI-(RCORR-2); wxI++ ) {
RegressI( &D, &vD, &logrFP[wxI-1], &logcrFP[wxI-1], RCORR );
regFP[wxI] = D;
}
regFP[wxI] = 0.; /* make things clean */
Done:
if ( ThetaLP != (long *)0 ) free( (void *)ThetaLP );
return( rcI );
}
/************************************************************************
* *
* LyapunovI() - Compute the Largest Lyapunov Exponent *
* *
************************************************************************
The return arrays are:
zlyapFP - lyapunov exponent estimate
EvolveItFP - Evolution * Iterations
diFP - distance
DFFP - starting distance
regFP - regression [0=all; 1.. = 3-element]
Each of these MUST be dimensioned nI/EvolveI in length.
The function returns negative return codes for errors.
Positive return codes are the number of items in the return
arrays.
This code has been verified against Wolfe's FORTRAN program.
*/
int LyapunovI( zlyapFP, EvolveItFP, diFP, DFFP,
xFP, nI, DimI, tauI, dtD, ScaleMaxD, ScaleMinD,
EvolveI, LagI )
float *zlyapFP; /* (r) lyapunov exponent estimate */
float *EvolveItFP; /* (r) evolution * iterations */
float *diFP; /* (r) distance at this level */
float *DFFP; /* (r) maximum distance at start */
float *xFP; /* (i) input data vector */
int nI; /* (i) number of points in data vector */
int DimI; /* (i) embedding dimension */
int tauI; /* (i) phase shift for reconstructing phase space */
double dtD; /* (i) increase in each measurement */
double ScaleMaxD; /* (i) maximum divergence */
double ScaleMinD; /* (i) minimum divergence */
int EvolveI; /* (i) number of iterations to evolve */
int LagI; /* (i) minimum time between pairs */
/* NOTE: tauI <= LagI < 12. */
{
int nptI; /* effective number of points in data set */
int ind1I, ind2I; /* indices into phase */
int indoldI; /* last ind2I value */
int wI; /* work integer */
int i,j,k; /* work indices for loops */
int jTauI; /* work variable to reduce computation */
int FirstFlagI; /* first time flag */
int rcI=0; /* return code */
double D; /* work value */
double diD; /* "di" in wingz */
double diiD; /* "dii" in wingz */
double vD; /* temp work value */
double DF; /* final divergence */
double TotalD; /* accumulator */
int ItersI; /* # of iterations */
double zlyapD; /* lyapunov exponent? */
double zmultD; /* z-multiplier */
double anglmxD; /* maximum angle */
double thminD; /* theta minimum */
double DNewD; /* new distance */
double dotD; /* ? */
double cthD; /* cosine theta */
double thD; /* theta */
double *pt1DP=0; /* pointer to work area */
double *pt2DP=0; /* ditto... */
double Log2D; /* log of 2.0 */
double mD, bD; /* slope & intercept */
if ( (pt1DP=(double *)malloc( (DimI+2)*sizeof(*pt1DP) )) == (double *)0
|| (pt2DP=(double *)malloc( (DimI+2)*sizeof(*pt2DP) )) == (double *)0 ) {
rcI = -1;
goto Done;
}
for( wI = 0; wI < nI; wI++ ) {
zlyapFP[wI] = 0.0;
EvolveItFP[wI] = 0.0;
diFP[wI] = 0.0;
DFFP[wI] = 0.0;
}
nptI = nI - (DimI * tauI + EvolveI);
FirstFlagI = 1; /* first time hit */
ind1I = ind2I = 0; /* first index */
diiD = diD = 0.;
for( i = LagI+1; i < nptI; i++ ) {
D = 0.;
for( j = jTauI = 0; j < DimI; j++, jTauI += tauI ) {
vD = xFP[ jTauI + ind1I ] - xFP[ jTauI + i ];
D += vD * vD;
}
D = sqrt(D);
if ( (FirstFlagI || D <= diD) && D >= ScaleMinD ) {
diD = D; /* smallest point > ScaleMinD */
ind2I = i;
FirstFlagI = 0;
}
}
if ( FirstFlagI ) { rcI = -2; goto Done; }
TotalD = 0.0;
Log2D = log(2.);
for( ItersI = 1; ; ItersI++) {
/* --- Save Coordinates of Evolved points --- */
DF = 0.;
for( j = 0; j < DimI; j++ ) {
pt1DP[j] = xFP[ ind1I + EvolveI + j * tauI ];
pt2DP[j] = xFP[ ind2I + EvolveI + j * tauI ];
vD = pt1DP[j] - pt2DP[j];
DF += vD * vD;
}
DF = sqrt( DF ); /* final divergence */
TotalD += log(DF/diD) / (EvolveI * dtD * Log2D );
zlyapD = TotalD / ItersI;
/* --- pass data back to calling program --- */
wI = ItersI - 1;
zlyapFP[wI] = zlyapD;
EvolveItFP[wI] = ((double)EvolveI) * ((double) ItersI);
diFP[wI] = diD;
DFFP[wI] = DF;
if ( diD > 5000. || DF > 5000. )
break;
indoldI = ind2I;
zmultD = 1.0;
anglmxD = 0.3;
for(;;) {
thminD = 3.14;
/* --- look for replacement points --- */
for( i = 0; i < nptI; i++ ) {
wI = i - (ind1I + EvolveI);
if ( -LagI < wI && wI < LagI )
continue; /* too close */
DNewD = 0.;
for( jTauI=i, j=0; j < DimI; j++, jTauI += tauI ) {
vD = pt1DP[j] - xFP[jTauI];
DNewD += vD * vD;
}
DNewD = sqrt(DNewD);
if ( DNewD > (zmultD * ScaleMaxD) || DNewD < ScaleMinD )
continue;
dotD = 0.;
for( jTauI=i, j=0; j < DimI; j++, jTauI += tauI )
dotD += (pt1DP[j] - xFP[jTauI]) * (pt1DP[j] - pt2DP[j]);
cthD = fabs( dotD / (DNewD * DF) ); /* per Peters */
if ( cthD > 1. ) cthD = 1.;
thD = acos(thD); /* thD = cos(thd) does not make sense */
if ( thD <= thminD ) {
thminD = thD;
ind2I = i;
diiD = DNewD;
}
}
if ( thminD < anglmxD ) goto EvolveInd1;
/* --- thminD >= anglmxD --- */
zmultD += 1.;
if ( zmultD < 5. ) continue;
zmultD = 1.;
anglmxD *= 2.;
if ( anglmxD >= 3.14 )
break;
}
ind2I = indoldI + EvolveI;
diiD = DF;
EvolveInd1:
ind1I += EvolveI;
if ( ind1I >= nptI ) break;
diD = diiD;
}
rcI = ItersI;
Done:
if ( pt1DP != (double *)0 ) free( (void *)pt1DP );
if ( pt2DP != (double *)0 ) free( (void *)pt2DP );
return( rcI );
}